package NewTmas.Graphs;

import NewTmas.FramesandPanels.JobGraphPanel;
import NewTmas.Listeners.OpsModeMouseAdaptor;
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
import com.mxgraph.model.mxCell;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.view.mxEdgeStyle;
import com.mxgraph.view.mxGraph;
import taskmaster.job.Dependency;
import taskmaster.job.JobAllTasksCollection;
import taskmaster.job.TaskStatus;
import taskmaster.util.Global;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: abhatnag
 * Date: 7/11/11
 * Time: 9:51 AM
 * To change this template use File | Settings | File Templates.
 */
public class JGraphGenerated {

    List<Dependency> dependencies;
    public HashMap<String, TaskStatus> task_status;
    HashMap<String,Character> taskType;
    public HashMap<String,String> display_name;

    public mxGraphComponent graphComponent;
    public mxGraph graph;


    public JGraphGenerated(JobAllTasksCollection allTc){


        this.dependencies=allTc.dependency_task;
        this.display_name=allTc.defaultNames;

        this.taskType=allTc.task_type;

        graph = createGraph();
        graphComponent = new mxGraphComponent(graph);
        graphComponent.setCenterZoom(true);

        graphComponent.setPanning(true);
        graphComponent.getViewport().setOpaque(true);
        graphComponent.getViewport().setBackground(Color.WHITE);

        graphComponent.setConnectable(false);

        MouseWheelListener wheelTracker = new MouseWheelListener() {
            public void mouseWheelMoved(MouseWheelEvent e) {
                if (e.isControlDown()) {

                    mouseWheelZoom(e);
                }
            }
        };
        graphComponent.addMouseWheelListener(wheelTracker);


    }




    public JGraphGenerated(List<Dependency> dependencies, HashMap<String, TaskStatus> task_status, HashMap<String, Character> taskType, HashMap<String, String> display_name, JobGraphPanel jobGraphPanel) {

        this.task_status=task_status;
        this.dependencies=dependencies;
        this.display_name=display_name;
        this.taskType=taskType;

        graph = createGraph();
        graphComponent = new mxGraphComponent(graph);
        graphComponent.setCenterZoom(true);

        graphComponent.setPanning(true);
        graphComponent.getViewport().setOpaque(true);
        graphComponent.getViewport().setBackground(Color.WHITE);
        graphComponent.setConnectable(false);
        graphComponent.getGraph().setCellsSelectable(false);
        graphComponent.getGraph().setCellsEditable(false);

        MouseWheelListener wheelTracker = new MouseWheelListener() {
            public void mouseWheelMoved(MouseWheelEvent e) {
                if (e.isControlDown()) {

                    mouseWheelZoom(e);
                }
            }
        };
        graphComponent.addMouseWheelListener(wheelTracker);

        /* Popup MouseListener for every vertex*/
        MouseListener pop = new OpsModeMouseAdaptor(this,jobGraphPanel);
        graphComponent.getGraphControl().addMouseListener(pop);

    }



    protected void mouseWheelZoom(MouseWheelEvent e) {
        if (e.getWheelRotation() < 0) {
            graphComponent.zoomIn();

        } else {
            graphComponent.zoomOut();
        }

    }



    public mxGraph createGraph(){

        mxGraph graph = new mxGraph();
        Object parent = graph.getDefaultParent();



        graph.getModel().beginUpdate();
        Map<String, mxCell> vertexSet = new HashMap<String, mxCell >();
        try
        {
            graph.setAutoSizeCells(true);
            StringBuffer vertexColor=new StringBuffer();
            /* for plotting those tasks found in the dependency table*/
            for(Dependency entry: dependencies)
            {
                String from = entry.getDependency();

                Object v0, v1;

                if(!vertexSet.containsKey(from)) {
                    //in case the task does not have a status and for edit mode tasks when task_status is null
                    if(task_status==null || !task_status.containsKey(from))
                    {
                        vertexColor.replace(0,vertexColor.length(),"shape="+ Global.task_shape.get(taskType.get(from))+";perimeter=100;perimeter="+Global.task_shape.get(taskType.get(from))+"Perimeter;whiteSpace=wrap;fontColor=black;");
                    }
                    else
                    {

                        vertexColor.replace(0,vertexColor.length(),"shape="+ Global.task_shape.get(taskType.get(from))+";perimeter=100;perimeter="+Global.task_shape.get(taskType.get(from))+"Perimeter;whiteSpace=wrap;fontColor=black;fillColor="+task_status.get(from).getColor()+";");
                    }
                    v0=graph.insertVertex(graph.getDefaultParent(), null,display_name.get(from), 0, 0,150,60,vertexColor.toString());
                    vertexSet.put(from,(mxCell)v0);


                }
                else {
                    v0 = vertexSet.get(from);
                }
                String to = entry.getTask();
                if(!vertexSet.containsKey(to)) {


                    if(task_status==null || !task_status.containsKey(to))
                    {
                        vertexColor.replace(0,vertexColor.length(),"shape="+ Global.task_shape.get(taskType.get(to))+";perimeter=100;perimeter="+Global.task_shape.get(taskType.get(to))+"Perimeter;whiteSpace=wrap;fontColor=black;");
                    }
                    else
                    {

                        vertexColor.replace(0,vertexColor.length(),"shape="+ Global.task_shape.get(taskType.get(to))+";perimeter=100;perimeter="+Global.task_shape.get(taskType.get(to))+"Perimeter;whiteSpace=wrap;fontColor=black;fillColor="+task_status.get(to).getColor()+";");
                    }


                    v1=graph.insertVertex(graph.getDefaultParent(), null,display_name.get(to),0,0,150,60,vertexColor.toString());

                    vertexSet.put(to, (mxCell)v1);


                }
                else {

                    v1 = vertexSet.get(to);
                }
                Map<String, Object> style = graph.getStylesheet().getDefaultEdgeStyle();
                style.put(mxConstants.STYLE_EDGE, mxEdgeStyle.ElbowConnector);


                if(display_name.get(to)!=null && display_name.get(from)!=null)
                {
                    graph.insertEdge(graph.getDefaultParent(), null, "", v0, v1);
                }
            }



            Object v3;

            int m=7000,n=0;
            /* for plotting those tasks not found in the dependency table*/



            for(String s: taskType.keySet()){



                if(!vertexSet.containsKey(s))
                {
                    if(task_status==null || !task_status.containsKey(s))
                    {
                        vertexColor.replace(0,vertexColor.length(),"shape="+ Global.task_shape.get(taskType.get(s))+";perimeter=100;perimeter="+Global.task_shape.get(taskType.get(s))+"Perimeter;whiteSpace=wrap;fontColor=black;");
                    }
                    else
                    {

                        vertexColor.replace(0, vertexColor.length(), "shape=" + Global.task_shape.get(taskType.get(s)) + ";perimeter=100;perimeter=" + Global.task_shape.get(taskType.get(s)) + "Perimeter;whiteSpace=wrap;fontColor=black;fillColor=" + task_status.get(s).getColor() + ";");
                    }
                    v3=graph.insertVertex(graph.getDefaultParent(),null,display_name.get(s),m,n,160,70,vertexColor.toString());
                    vertexSet.put(s,(mxCell)v3);
                    m=m-200;

                }

            }

        }
        finally
        {


            mxHierarchicalLayout layout = new mxHierarchicalLayout(graph, SwingConstants.VERTICAL);
            layout.setIntraCellSpacing(20);
            graph.setCellsEditable(false);
            graph.setCellsSelectable(false)  ;
            graph.getModel().endUpdate();

            layout.execute(parent);
        }
        return graph;

    }



    public void refreshGraphObject(){
        graphComponent.setGraph(createGraph());
        graphComponent.refresh();

    }
}

